import cv2 as cv
from Find_Contour import findContours
from kalmanfilter import KalmanFilter
kf = KalmanFilter()

#类 摄像头
class Camera():
    #fps:摄像头帧率 cap:cv.VideoCapture打开的文件或摄像头
    def __init__(self,fps,cap):
        self.fps = fps
        self.cap = cap
    #摄像头参数设置    
    def Open(self):
        self.cap.set(cv.CAP_PROP_FPS, self.fps)
        return self.cap
    #显示
    def Show(self,name,frame):
        #name：窗口命名
        cv.namedWindow(name, cv.WINDOW_AUTOSIZE)
        cv.imshow(name, frame)
    #关闭相机
    def Quit(self):
        self.cap.release()
        cv.destroyAllWindows()

#类 目标物体
class Object():
    #检测目标物体，找到装甲板中心点
    def Dec(self,frame,a,b):
        #获得轮廓坐标
        light_bbox,i = findContours(frame,5,2,50)
        #当检测到至少一个目标时
        if i > 0:
            x, y, x2, y2 = light_bbox[0]
            #求矩形中心点
            cx = int((x + x2) / 2)
            cy = int((y + y2) / 2)
            cv.rectangle(frame, (x, y), (x2, y2), (0, 0, 255), 4)
            #检测到多于一个目标时
            if i > 1:
                X, Y, X2, Y2 = light_bbox[1]
                #求矩形中心点
                cX = int((X + X2) / 2)
                cY = int((Y + Y2) / 2)
                cv.rectangle(frame, (X, Y), (X2, Y2), (0, 0, 255), 4)
                #求装甲板中心点
                a = int((cx + cX) / 2)
                b = int((cy + cY) / 2)
                cv.circle(frame, (a, b), 10, (0, 0, 255), 4)
        
        return a,b,i
    #移动预测
    #a,b：装甲板中心点坐标
    def Pre(self,a,b):
        #用卡尔曼滤波预测
        predicted = kf.predict(a, b)
        #画出预测点
        cv.circle(frame, (predicted[0], predicted[1]), 7, (255, 0, 0), 4)
        return predicted[0],predicted[1]

#创建两个类变量
c1 = Camera(25,cv.VideoCapture("D:/All_About_Study/装甲板测试视频.avi"))
o1 = Object()

CAP = c1.Open()
a=b=0
fps = CAP.get(cv.CAP_PROP_FPS)

while True:
    ret, frame = CAP.read()
    if ret is False:
        break

    a,b,i = o1.Dec(frame,a,b)
    
    #只有检测到两个轮廓时，即存在中心点时才进行预测
    if i > 0:
        A,B = o1.Pre(a,b)

    c1.Show('video',frame)
    cv.waitKey(int(fps))
    if cv.waitKey(1) == 27:
        break
c1.Quit()       